﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace P3SS.Networking
{
	/// <summary>
	/// Occurs when an error happens in a protocol
	/// </summary>
	[global::System.Serializable]
	public class ProtocolErrorException : Exception
	{
		/// <summary>
		/// Maximum size for a server response (max size for a log message is 32766 chars)
		/// </summary>
		private const int MAX_SERVER_RESPONSE = 10000;

		#region Constructor
		/// <summary>
		/// Default constructor
		/// </summary>
		public ProtocolErrorException() { }
		/// <summary>
		/// Input constructor
		/// </summary>
		/// <param name="message">Message describing the error</param>
		public ProtocolErrorException(string message) : base(message) 
		{}
		/// <summary>
		/// Input Constructor
		/// </summary>
		/// <param name="message">Message describing the error</param>
		/// <param name="inner">Exception that caused this exception to be thrown</param>
		public ProtocolErrorException(string message, Exception inner)
			: base(message, inner) 
		{
		}
		/// <summary>
		/// Input Constructor
		/// </summary>
		/// <param name="message">Messsage describing the error</param>
		/// <param name="inServerResponse">The response that the server sent</param>
		/// <param name="inCommandSent">Command sent by protocol that caused the error</param>
		public ProtocolErrorException(string message, string inServerResponse, string inCommandSent) : base(message)
		{
			if (inServerResponse.Length > MAX_SERVER_RESPONSE)
			{
				ServerResponse = inServerResponse.Substring(0, MAX_SERVER_RESPONSE);
			}
			else
			{
				ServerResponse = inServerResponse;
			}
			CommandSent = inCommandSent;
		}
		/// <summary>
		/// Input Constructor
		/// </summary>
		/// <param name="info"></param>
		/// <param name="context"></param>
		protected ProtocolErrorException(
		  System.Runtime.Serialization.SerializationInfo info,
		  System.Runtime.Serialization.StreamingContext context)
			: base(info, context) { }
		#endregion
		#region Properties
		/// <summary>
		/// The unexpected text that the server responded with
		/// </summary>
		public string ServerResponse { get; private set; }
		public string CommandSent { get; private set; }
		#endregion
		#region Public Methods
		/// <summary>
		/// Human readable string representing this object
		/// </summary>
		/// <returns>Human readable string specifying the error, server reponse and stack trace</returns>
		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendFormat("{0}\r\n\r\nCommand Sent: \r\n{2}\r\n\r\nServer reponse: \r\n{1}\r\n\r\nStackTrace:\r\n{3}", Message, ServerResponse, CommandSent, StackTrace);

			if (this.InnerException != null)
			{
				sb.Append("\r\n\r\nInner Exception:\r\n");
				sb.Append(this.InnerException);
			}

			return sb.ToString();
		}
		#endregion
	}
}
